package com.gitee.openviducn.inspector.auth;

import com.alibaba.fastjson.JSON;
import com.gitee.openviducn.inspector.common.ResponseError;
import com.gitee.openviducn.inspector.common.ResponseResult;
import com.gitee.openviducn.inspector.constant.AppConstant;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 鉴权拦截器
 * @Author: https://gitee.com/wesleyOne
 * @Date: 03.02 2020
 * 参考[https://github.com/alibaba/Sentinel/]控制台项目
 */
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    @Resource
    private AuthService<HttpServletRequest> authService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(!handler.getClass().isAssignableFrom(HandlerMethod.class)){
            return true;
        }
        Method method = ((HandlerMethod)handler).getMethod();
        boolean isResponseBody = handler.getClass().isAnnotationPresent(RestController.class);
        if (!isResponseBody) {
            isResponseBody = method.isAnnotationPresent(ResponseBody.class);
        }
        if (!isResponseBody) {
            return true;
        }

        AuthAction authAction = method.getAnnotation(AuthAction.class);
        if (Objects.isNull(authAction)) {
            return true;
        }

        AuthService.AuthUser authUser = authService.getAuthUser(request);
        if (authUser == null) {
            responseNoPrivilegeMsg(response, authAction.message());
            return false;
        }
        request.setAttribute(AppConstant.REQUEST_USER, authUser);
        String target = request.getParameter(authAction.targetName());
        if (!authUser.authTarget(target, authAction.roles())) {
            responseNoPrivilegeMsg(response, authAction.message());
            return false;
        }
        return true;
    }


    private void responseNoPrivilegeMsg(HttpServletResponse response, String message) throws IOException {
        ResponseResult<Void> error = ResponseResult.error(ResponseError.AUTH_ERROR, message);
        response.addHeader("Content-Type", "application/json;charset=UTF-8");
        response.getOutputStream().write(JSON.toJSONBytes(error));
    }
}
